/*
 * This file is part of the Sx Framework Library.
 * 
 * Copyright (C) 2013 University of Colorado Denver
 * <min.choi@ucdenver.edu> <shane.transue@ucdenver.edu>
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy 
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
 * copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 * DEALINGS IN THE SOFTWARE.
 */
#ifndef SX_MOUSE_MOVEMENT_CONTROLLER_H
#define SX_MOUSE_MOVEMENT_CONTROLLER_H

#include <sxMouse.h>
#include <sxCamera.h>

using Sx::Graphics::Objects::Camera;

namespace Sx {
namespace Interface {

/*
 * The MouseMovementController class provides an interface for the mouse
 * controls that move the camera in a viewport controlled by a viewport
 * controller. Extending this class and changing an existing ViewportController
 * to use the newly created class that implements this interface provides a way
 * to change the cameras mouse controls (how the camera moves based on the
 * input mouse movements). All of these operations are only related to when
 * the user is moving the mouse and one or more of the mouse buttons is being
 * held down during the movement (commonly referred to as a mouse drag event)
 * or the mouse wheel is rotated.
 */
class MouseMovementController {
public:
  /*
   * These functions are ment to be called from within a ViewportController 
   * class during the MouseMove event. When the mouse moves in the viewport 
   * controlled by a ViewportController, one or more of the mouse buttons could 
   * be pressed. If this is the case then one of the following functions should 
   * be called to move the view presented by the controlled viewport. These 
   * functions define the interface that allows for new mouse-based viewport 
   * camera controls to be implemented. The new controls can be implemented by
   * extending this class and implementing this interface, followed by setting
   * the MouseMovementController in the desired ViewportController class to an 
   * instance of the new type.
   *  
   *  class MyMouseController : public MouseMovementController { . overloads . }
   *
   *  ViewportController vc = viewport->getController();
   *  MyMouseController myMouseController;
   *  vc.setMouseMovementController(myMouseController);
   *
   * This will enable the viewport controller vc to use the newly defined mouse
   * controls defined in the new MyMouseController class.
   *
   * A pointer to the camera to be modified is provided along with how far the
   * mouse pointer has been dragged (the difference between the last mouse
   * position and the new mouse position - where the drag operations starts and
   * ends).
   */
	virtual void onMouse_Left_Drag(Camera* const camera, int xDifference, int yDifference, ModifierKey modifierKey) = 0;
	virtual void onMouse_Right_Drag(Camera* const camera, int xDifference, int yDifference, ModifierKey modifierKey) = 0;
	virtual void onMouse_Middle_Drag(Camera* const camera, int xDifference, int yDifference, ModifierKey modifierKey) = 0;
	virtual void onMouse_LeftAndRight_Drag(Camera* const camera, int xDifference, int yDifference, ModifierKey modifierKey) = 0;
	virtual void onMouse_Wheel_Rotate(Camera* const camera, int delta) = 0;
};

}

}

#endif
